#include "index_manager.h"
#include "hash_index.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdatomic.h>

// Index manager creation
index_manager_t* index_manager_create(memory_manager_t* memory_mgr) {
    if (!memory_mgr) return NULL;
    
    index_manager_t* mgr = malloc(sizeof(index_manager_t));
    if (!mgr) return NULL;
    
    memset(mgr, 0, sizeof(index_manager_t));
    
    // Initialize index array
    mgr->capacity = 32;  // Initial capacity
    mgr->indexes = calloc(mgr->capacity, sizeof(index_instance_t*));
    if (!mgr->indexes) {
        free(mgr);
        return NULL;
    }
    
    mgr->memory_mgr = memory_mgr;
    
    // Initialize read-write lock
    if (pthread_rwlock_init(&mgr->rwlock, NULL) != 0) {
        free(mgr->indexes);
        free(mgr);
        return NULL;
    }
    
    // Initialize type interfaces
    mgr->type_interfaces[INDEX_TYPE_BW_TREE] = bw_tree_interface_create();
    mgr->type_interfaces[INDEX_TYPE_BTREE] = btree_interface_create();
    mgr->type_interfaces[INDEX_TYPE_HASH] = hash_index_interface_create();
    mgr->type_interfaces[INDEX_TYPE_BITMAP] = bitmap_index_interface_create();
    mgr->type_interfaces[INDEX_TYPE_RTREE] = rtree_interface_create();
    
    return mgr;
}

void index_manager_destroy(index_manager_t* mgr) {
    if (!mgr) return;
    
    pthread_rwlock_wrlock(&mgr->rwlock);
    
    // Destroy all indexes
    for (uint32_t i = 0; i < mgr->count; i++) {
        if (mgr->indexes[i]) {
            if (mgr->indexes[i]->interface && mgr->indexes[i]->interface->destroy) {
                mgr->indexes[i]->interface->destroy(mgr->indexes[i]);
            }
        }
    }
    
    // Free type interfaces
    for (int i = 0; i < INDEX_TYPE_COUNT; i++) {
        free(mgr->type_interfaces[i]);
    }
    
    pthread_rwlock_unlock(&mgr->rwlock);
    pthread_rwlock_destroy(&mgr->rwlock);
    
    free(mgr->indexes);
    free(mgr);
}

// Index creation
index_instance_t* index_create(index_manager_t* mgr, const char* name, 
                              const index_config_t* config) {
    if (!mgr || !name || !config || config->type >= INDEX_TYPE_COUNT) {
        return NULL;
    }
    
    pthread_rwlock_wrlock(&mgr->rwlock);
    
    // Check if index already exists
    for (uint32_t i = 0; i < mgr->count; i++) {
        if (mgr->indexes[i] && strcmp(mgr->indexes[i]->name, name) == 0) {
            pthread_rwlock_unlock(&mgr->rwlock);
            return NULL; // Index already exists
        }
    }
    
    // Expand array if needed
    if (mgr->count >= mgr->capacity) {
        uint32_t new_capacity = mgr->capacity * 2;
        index_instance_t** new_indexes = realloc(mgr->indexes, 
                                                 new_capacity * sizeof(index_instance_t*));
        if (!new_indexes) {
            pthread_rwlock_unlock(&mgr->rwlock);
            return NULL;
        }
        
        // Initialize new slots
        for (uint32_t i = mgr->capacity; i < new_capacity; i++) {
            new_indexes[i] = NULL;
        }
        
        mgr->indexes = new_indexes;
        mgr->capacity = new_capacity;
    }
    
    // Create index instance
    index_instance_t* index = malloc(sizeof(index_instance_t));
    if (!index) {
        pthread_rwlock_unlock(&mgr->rwlock);
        return NULL;
    }
    
    memset(index, 0, sizeof(index_instance_t));
    
    // Initialize index
    index->type = config->type;
    index->interface = mgr->type_interfaces[config->type];
    index->config = *config;
    index->memory_mgr = mgr->memory_mgr;
    strncpy(index->name, name, sizeof(index->name) - 1);
    
    if (pthread_rwlock_init(&index->rwlock, NULL) != 0) {
        free(index);
        pthread_rwlock_unlock(&mgr->rwlock);
        return NULL;
    }
    
    atomic_init(&index->is_destroyed, false);
    
    // Create type-specific index data
    switch (config->type) {
        case INDEX_TYPE_HASH: {
            uint32_t bucket_count = config->bucket_count > 0 ? config->bucket_count : 1024;
            double load_factor = config->load_factor > 0.0 ? config->load_factor : 0.75;
            
            // Include hash_index.h and use its factory function
            extern hash_index_t* hash_index_create(memory_manager_t* memory_mgr, 
                                                  uint32_t initial_buckets,
                                                  double max_load_factor);
            index->index_data = hash_index_create(mgr->memory_mgr, bucket_count, load_factor);
            break;
        }
        case INDEX_TYPE_BW_TREE: {
            // Create Bw-tree instance
            extern bw_tree_t* bw_tree_create(memory_manager_t* memory_mgr);
            index->index_data = bw_tree_create(mgr->memory_mgr);
            break;
        }
        case INDEX_TYPE_BTREE: {
            // Create B+ tree instance
            uint32_t node_size = config->node_size > 0 ? config->node_size : 4096;
            extern btree_t* btree_create(memory_manager_t* memory_mgr, uint32_t node_size);
            index->index_data = btree_create(mgr->memory_mgr, node_size);
            break;
        }
        case INDEX_TYPE_BITMAP: {
            // Create bitmap index instance
            uint32_t initial_capacity = config->initial_capacity > 0 ? config->initial_capacity : 10000;
            extern bitmap_index_t* bitmap_index_create(memory_manager_t* memory_mgr, uint32_t initial_capacity);
            index->index_data = bitmap_index_create(mgr->memory_mgr, initial_capacity);
            break;
        }
        case INDEX_TYPE_RTREE: {
            // Create R-tree instance
            uint32_t node_size = config->node_size > 0 ? config->node_size : 2048;
            extern rtree_t* rtree_create(memory_manager_t* memory_mgr, uint32_t node_size);
            index->index_data = rtree_create(mgr->memory_mgr, node_size);
            break;
        }
        default:
            // Not implemented yet
            index->index_data = NULL;
            break;
    }
    
    // Add to manager
    mgr->indexes[mgr->count++] = index;
    mgr->total_indexes_created++;
    
    pthread_rwlock_unlock(&mgr->rwlock);
    return index;
}

// Index lookup
index_instance_t* index_get(index_manager_t* mgr, const char* name) {
    if (!mgr || !name) return NULL;
    
    pthread_rwlock_rdlock(&mgr->rwlock);
    
    for (uint32_t i = 0; i < mgr->count; i++) {
        if (mgr->indexes[i] && strcmp(mgr->indexes[i]->name, name) == 0) {
            index_instance_t* index = mgr->indexes[i];
            pthread_rwlock_unlock(&mgr->rwlock);
            return index;
        }
    }
    
    pthread_rwlock_unlock(&mgr->rwlock);
    return NULL;
}

// Index deletion
index_result_t index_drop(index_manager_t* mgr, const char* name) {
    if (!mgr || !name) return INDEX_ERROR_INVALID_PARAM;
    
    pthread_rwlock_wrlock(&mgr->rwlock);
    
    for (uint32_t i = 0; i < mgr->count; i++) {
        if (mgr->indexes[i] && strcmp(mgr->indexes[i]->name, name) == 0) {
            index_instance_t* index = mgr->indexes[i];
            
            // Mark as destroyed
            atomic_store(&index->is_destroyed, true);
            
            // Destroy index
            if (index->interface && index->interface->destroy) {
                index->interface->destroy(index);
            }
            
            // Remove from array
            for (uint32_t j = i; j < mgr->count - 1; j++) {
                mgr->indexes[j] = mgr->indexes[j + 1];
            }
            mgr->count--;
            mgr->indexes[mgr->count] = NULL;
            
            pthread_rwlock_unlock(&mgr->rwlock);
            return INDEX_SUCCESS;
        }
    }
    
    pthread_rwlock_unlock(&mgr->rwlock);
    return INDEX_ERROR_KEY_NOT_FOUND;
}

// Generic index operations - delegate to specific implementations

index_result_t index_insert(index_instance_t* index, const void* key, size_t key_size,
                           const void* value, size_t value_size) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (!index->interface || !index->interface->insert) {
        return INDEX_ERROR_TYPE_MISMATCH;
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    index_result_t result = index->interface->insert(index, key, key_size, value, value_size);
    pthread_rwlock_unlock(&index->rwlock);
    
    // Update statistics
    __atomic_fetch_add(&index->stats.total_operations, 1, __ATOMIC_SEQ_CST);
    if (result == INDEX_SUCCESS) {
        __atomic_fetch_add(&index->stats.inserts, 1, __ATOMIC_SEQ_CST);
        __atomic_fetch_add(&index->stats.total_keys, 1, __ATOMIC_SEQ_CST);
    }
    
    return result;
}

index_result_t index_delete(index_instance_t* index, const void* key, size_t key_size) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (!index->interface || !index->interface->delete) {
        return INDEX_ERROR_TYPE_MISMATCH;
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    index_result_t result = index->interface->delete(index, key, key_size);
    pthread_rwlock_unlock(&index->rwlock);
    
    // Update statistics
    __atomic_fetch_add(&index->stats.total_operations, 1, __ATOMIC_SEQ_CST);
    if (result == INDEX_SUCCESS) {
        __atomic_fetch_add(&index->stats.deletes, 1, __ATOMIC_SEQ_CST);
        __atomic_fetch_sub(&index->stats.total_keys, 1, __ATOMIC_SEQ_CST);
    }
    
    return result;
}

index_result_t index_update(index_instance_t* index, const void* key, size_t key_size,
                           const void* value, size_t value_size) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (!index->interface || !index->interface->update) {
        return INDEX_ERROR_TYPE_MISMATCH;
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    index_result_t result = index->interface->update(index, key, key_size, value, value_size);
    pthread_rwlock_unlock(&index->rwlock);
    
    // Update statistics
    __atomic_fetch_add(&index->stats.total_operations, 1, __ATOMIC_SEQ_CST);
    if (result == INDEX_SUCCESS) {
        __atomic_fetch_add(&index->stats.updates, 1, __ATOMIC_SEQ_CST);
    }
    
    return result;
}

index_result_t index_search(index_instance_t* index, const void* key, size_t key_size,
                           index_search_result_t* result) {
    if (!index || !result || atomic_load(&index->is_destroyed)) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (!index->interface || !index->interface->search) {
        return INDEX_ERROR_TYPE_MISMATCH;
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    index_result_t search_result = index->interface->search(index, key, key_size, result);
    pthread_rwlock_unlock(&index->rwlock);
    
    // Update statistics
    __atomic_fetch_add(&index->stats.total_operations, 1, __ATOMIC_SEQ_CST);
    __atomic_fetch_add(&index->stats.searches, 1, __ATOMIC_SEQ_CST);
    
    return search_result;
}

// Range operations
index_iterator_t* index_range_scan(index_instance_t* index,
                                  const void* start_key, size_t start_key_size,
                                  const void* end_key, size_t end_key_size,
                                  bool forward) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return NULL;
    }
    
    if (!index->interface || !index->interface->range_scan) {
        return NULL;
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    index_iterator_t* iter = index->interface->range_scan(index, 
                                                         start_key, start_key_size,
                                                         end_key, end_key_size,
                                                         forward);
    pthread_rwlock_unlock(&index->rwlock);
    
    if (iter) {
        __atomic_fetch_add(&index->stats.range_scans, 1, __ATOMIC_SEQ_CST);
    }
    
    return iter;
}

// Iterator operations
bool index_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->index || !iter->index->interface) {
        return false;
    }
    
    return iter->index->interface->iterator_valid(iter);
}

index_result_t index_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->index || !iter->index->interface) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    return iter->index->interface->iterator_next(iter);
}

index_result_t index_iterator_current(index_iterator_t* iter,
                                     void** key, size_t* key_size,
                                     void** value, size_t* value_size) {
    if (!iter || !iter->index || !iter->index->interface) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    return iter->index->interface->iterator_current(iter, key, key_size, value, value_size);
}

void index_iterator_destroy(index_iterator_t* iter) {
    if (!iter || !iter->index || !iter->index->interface) {
        return;
    }
    
    iter->index->interface->iterator_destroy(iter);
}

// Utility functions
const char* index_type_to_string(index_type_t type) {
    switch (type) {
        case INDEX_TYPE_BW_TREE: return "BW_TREE";
        case INDEX_TYPE_BTREE: return "B_TREE";
        case INDEX_TYPE_HASH: return "HASH";
        case INDEX_TYPE_BITMAP: return "BITMAP";
        case INDEX_TYPE_RTREE: return "R_TREE";
        default: return "UNKNOWN";
    }
}

const char* index_result_to_string(index_result_t result) {
    switch (result) {
        case INDEX_SUCCESS: return "SUCCESS";
        case INDEX_ERROR_KEY_NOT_FOUND: return "KEY_NOT_FOUND";
        case INDEX_ERROR_KEY_EXISTS: return "KEY_EXISTS";
        case INDEX_ERROR_INVALID_PARAM: return "INVALID_PARAM";
        case INDEX_ERROR_OUT_OF_MEMORY: return "OUT_OF_MEMORY";
        case INDEX_ERROR_TYPE_MISMATCH: return "TYPE_MISMATCH";
        case INDEX_ERROR_INDEX_FULL: return "INDEX_FULL";
        case INDEX_ERROR_CONCURRENT_UPDATE: return "CONCURRENT_UPDATE";
        case INDEX_ERROR_DESTROYED: return "DESTROYED";
        default: return "UNKNOWN";
    }
}

index_config_t index_default_config(index_type_t type) {
    index_config_t config;
    memset(&config, 0, sizeof(config));
    
    config.type = type;
    config.initial_capacity = 1000;
    config.max_key_size = 256;
    config.max_value_size = 1024;
    config.allow_duplicates = false;
    config.is_unique = true;
    config.is_primary = false;
    
    switch (type) {
        case INDEX_TYPE_BW_TREE:
        case INDEX_TYPE_BTREE:
            config.node_size = 4096;
            break;
        case INDEX_TYPE_HASH:
            config.load_factor = 0.75;
            config.bucket_count = 1024;
            break;
        case INDEX_TYPE_BITMAP:
            config.initial_capacity = 10000;
            break;
        case INDEX_TYPE_RTREE:
            config.node_size = 2048;
            break;
        default:
            break;
    }
    
    return config;
}

void index_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !stats) return;
    
    if (index->interface && index->interface->get_stats) {
        index->interface->get_stats(index, stats);
    } else {
        *stats = index->stats;
    }
}

void index_print_stats(index_instance_t* index) {
    if (!index) return;
    
    index_stats_t stats;
    index_get_stats(index, &stats);
    
    printf("Index Statistics for '%s' (%s):\n", index->name, 
           index_type_to_string(index->type));
    printf("  Total keys: %llu\n", (unsigned long long)stats.total_keys);
    printf("  Total operations: %llu\n", (unsigned long long)stats.total_operations);
    printf("  Searches: %llu\n", (unsigned long long)stats.searches);
    printf("  Inserts: %llu\n", (unsigned long long)stats.inserts);
    printf("  Deletes: %llu\n", (unsigned long long)stats.deletes);
    printf("  Updates: %llu\n", (unsigned long long)stats.updates);
    printf("  Range scans: %llu\n", (unsigned long long)stats.range_scans);
    printf("  Memory usage: %zu bytes\n", stats.memory_usage);
    printf("  Average chain length: %.2f\n", stats.avg_chain_length);
    printf("  Average depth: %.2f\n", stats.avg_depth);
    printf("  Collisions: %llu\n", (unsigned long long)stats.collisions);
    printf("  Rehashes: %llu\n", (unsigned long long)stats.rehashes);
}

// Clear operation
index_result_t index_clear(index_instance_t* index) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    if (!index->interface || !index->interface->clear) {
        return INDEX_ERROR_TYPE_MISMATCH;
    }
    
    pthread_rwlock_wrlock(&index->rwlock);
    index_result_t result = index->interface->clear(index);
    pthread_rwlock_unlock(&index->rwlock);
    
    if (result == INDEX_SUCCESS) {
        // Reset statistics
        memset(&index->stats, 0, sizeof(index->stats));
    }
    
    return result;
}

// Validation
bool index_validate(index_instance_t* index) {
    if (!index || atomic_load(&index->is_destroyed)) {
        return false;
    }
    
    if (!index->interface || !index->interface->validate) {
        return true; // No validation implemented
    }
    
    pthread_rwlock_rdlock(&index->rwlock);
    bool result = index->interface->validate(index);
    pthread_rwlock_unlock(&index->rwlock);
    
    return result;
}

// Placeholder implementations for type-specific interfaces
// These will be implemented in separate files

index_interface_t* bw_tree_interface_create(void) {
    index_interface_t* interface = malloc(sizeof(index_interface_t));
    if (!interface) return NULL;
    
    memset(interface, 0, sizeof(index_interface_t));
    
    // Core operations
    interface->insert = bw_tree_adapter_insert;
    interface->delete = bw_tree_adapter_delete;
    interface->update = bw_tree_adapter_update;
    interface->search = bw_tree_adapter_search;
    interface->exists = bw_tree_adapter_exists;
    
    // Range operations
    interface->range_scan = bw_tree_adapter_range_scan;
    
    // Iterator operations
    interface->iterator_valid = bw_tree_adapter_iterator_valid;
    interface->iterator_next = bw_tree_adapter_iterator_next;
    interface->iterator_current = bw_tree_adapter_iterator_current;
    interface->iterator_destroy = bw_tree_adapter_iterator_destroy;
    
    // Bulk operations
    interface->bulk_insert = bw_tree_adapter_bulk_insert;
    interface->range_delete = bw_tree_adapter_range_delete;
    
    // Management operations
    interface->clear = bw_tree_adapter_clear;
    interface->rebuild = bw_tree_adapter_rebuild;
    interface->destroy = bw_tree_adapter_destroy;
    
    // Statistics and monitoring
    interface->get_stats = bw_tree_adapter_get_stats;
    interface->validate = bw_tree_adapter_validate;
    
    // Configuration
    interface->set_config = bw_tree_adapter_set_config;
    interface->get_config = bw_tree_adapter_get_config;
    
    return interface;
}

index_interface_t* btree_interface_create(void) {
    index_interface_t* interface = malloc(sizeof(index_interface_t));
    if (!interface) return NULL;
    
    memset(interface, 0, sizeof(index_interface_t));
    
    // Core operations
    interface->insert = btree_adapter_insert;
    interface->delete = btree_adapter_delete;
    interface->update = btree_adapter_update;
    interface->search = btree_adapter_search;
    interface->exists = btree_adapter_exists;
    
    // Range operations
    interface->range_scan = btree_adapter_range_scan;
    
    // Iterator operations
    interface->iterator_valid = btree_adapter_iterator_valid;
    interface->iterator_next = btree_adapter_iterator_next;
    interface->iterator_current = btree_adapter_iterator_current;
    interface->iterator_destroy = btree_adapter_iterator_destroy;
    
    // Bulk operations
    interface->bulk_insert = btree_adapter_bulk_insert;
    interface->range_delete = btree_adapter_range_delete;
    
    // Management operations
    interface->clear = btree_adapter_clear;
    interface->rebuild = btree_adapter_rebuild;
    interface->destroy = btree_adapter_destroy;
    
    // Statistics and monitoring
    interface->get_stats = btree_adapter_get_stats;
    interface->validate = btree_adapter_validate;
    
    // Configuration
    interface->set_config = btree_adapter_set_config;
    interface->get_config = btree_adapter_get_config;
    
    return interface;
}

// Implemented in hash_index.c - remove placeholder
extern index_interface_t* hash_index_interface_create(void);

index_interface_t* bitmap_index_interface_create(void) {
    index_interface_t* interface = malloc(sizeof(index_interface_t));
    if (!interface) return NULL;
    
    memset(interface, 0, sizeof(index_interface_t));
    
    // Core operations
    interface->insert = bitmap_adapter_insert;
    interface->delete = bitmap_adapter_delete;
    interface->update = bitmap_adapter_update;
    interface->search = bitmap_adapter_search;
    interface->exists = bitmap_adapter_exists;
    
    // Range operations (limited support for bitmap)
    interface->range_scan = bitmap_adapter_range_scan;
    
    // Iterator operations
    interface->iterator_valid = bitmap_adapter_iterator_valid;
    interface->iterator_next = bitmap_adapter_iterator_next;
    interface->iterator_current = bitmap_adapter_iterator_current;
    interface->iterator_destroy = bitmap_adapter_iterator_destroy;
    
    // Bulk operations
    interface->bulk_insert = bitmap_adapter_bulk_insert;
    interface->range_delete = bitmap_adapter_range_delete;
    
    // Management operations
    interface->clear = bitmap_adapter_clear;
    interface->rebuild = bitmap_adapter_rebuild;
    interface->destroy = bitmap_adapter_destroy;
    
    // Statistics and monitoring
    interface->get_stats = bitmap_adapter_get_stats;
    interface->validate = bitmap_adapter_validate;
    
    // Configuration
    interface->set_config = bitmap_adapter_set_config;
    interface->get_config = bitmap_adapter_get_config;
    
    return interface;
}

index_interface_t* rtree_interface_create(void) {
    index_interface_t* interface = malloc(sizeof(index_interface_t));
    if (!interface) return NULL;
    
    memset(interface, 0, sizeof(index_interface_t));
    
    // Core operations
    interface->insert = rtree_adapter_insert;
    interface->delete = rtree_adapter_delete;
    interface->update = rtree_adapter_update;
    interface->search = rtree_adapter_search;
    interface->exists = rtree_adapter_exists;
    
    // Range operations (spatial queries for R-tree)
    interface->range_scan = rtree_adapter_range_scan;
    
    // Iterator operations
    interface->iterator_valid = rtree_adapter_iterator_valid;
    interface->iterator_next = rtree_adapter_iterator_next;
    interface->iterator_current = rtree_adapter_iterator_current;
    interface->iterator_destroy = rtree_adapter_iterator_destroy;
    
    // Bulk operations
    interface->bulk_insert = rtree_adapter_bulk_insert;
    interface->range_delete = rtree_adapter_range_delete;
    
    // Management operations
    interface->clear = rtree_adapter_clear;
    interface->rebuild = rtree_adapter_rebuild;
    interface->destroy = rtree_adapter_destroy;
    
    // Statistics and monitoring
    interface->get_stats = rtree_adapter_get_stats;
    interface->validate = rtree_adapter_validate;
    
    // Configuration
    interface->set_config = rtree_adapter_set_config;
    interface->get_config = rtree_adapter_get_config;
    
    return interface;
}

// ============================================================================
// Bw-Tree Adapter Implementation
// ============================================================================

// Forward declarations for Bw-tree functions
extern bw_tree_t* bw_tree_create(memory_manager_t* memory_mgr);
extern void bw_tree_destroy(bw_tree_t* tree);
extern bw_result_t bw_tree_insert(bw_tree_t* tree, const void* key, size_t key_size,
                                  const void* value, size_t value_size);
extern bw_result_t bw_tree_delete(bw_tree_t* tree, const void* key, size_t key_size);
extern bw_result_t bw_tree_update(bw_tree_t* tree, const void* key, size_t key_size,
                                  const void* value, size_t value_size);
extern bw_result_t bw_tree_search(bw_tree_t* tree, const void* key, size_t key_size,
                                  bw_search_result_t* result);
extern bw_iterator_t* bw_tree_scan(bw_tree_t* tree, const void* start_key, size_t start_key_size,
                                   const void* end_key, size_t end_key_size, bool forward);
extern bool bw_iterator_valid(bw_iterator_t* iter);
extern bw_result_t bw_iterator_next(bw_iterator_t* iter);
extern bw_result_t bw_iterator_current(bw_iterator_t* iter, void** key, size_t* key_size,
                                       void** value, size_t* value_size);
extern void bw_iterator_destroy(bw_iterator_t* iter);
extern bw_result_t bw_tree_bulk_insert(bw_tree_t* tree, bw_kv_pair_t** pairs, size_t count);
extern size_t bw_tree_range_delete(bw_tree_t* tree, const void* start_key, size_t start_key_size,
                                    const void* end_key, size_t end_key_size);
extern int bw_tree_clear(bw_tree_t* tree);
extern void bw_tree_get_stats(bw_tree_t* tree, bw_tree_stats_t* stats);
extern bool bw_tree_validate(bw_tree_t* tree);

// Helper function to convert bw_result_t to index_result_t
static index_result_t bw_result_to_index_result(bw_result_t bw_result) {
    switch (bw_result) {
        case BW_SUCCESS: return INDEX_SUCCESS;
        case BW_NOT_FOUND: return INDEX_NOT_FOUND;
        case BW_DUPLICATE_KEY: return INDEX_DUPLICATE_KEY;
        case BW_KEY_TOO_LARGE: return INDEX_KEY_TOO_LARGE;
        case BW_VALUE_TOO_LARGE: return INDEX_VALUE_TOO_LARGE;
        case BW_OUT_OF_MEMORY: return INDEX_OUT_OF_MEMORY;
        case BW_INVALID_ARGUMENT: return INDEX_INVALID_ARGUMENT;
        default: return INDEX_ERROR;
    }
}

// Core operations
static index_result_t bw_tree_adapter_insert(index_instance_t* index, 
                                           const void* key, size_t key_size,
                                           const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_result_t result = bw_tree_insert(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == BW_SUCCESS) {
        index->stats.inserts++;
        index->stats.total_operations++;
    }
    
    return bw_result_to_index_result(result);
}

static index_result_t bw_tree_adapter_delete(index_instance_t* index, 
                                           const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_result_t result = bw_tree_delete(tree, key, key_size);
    
    // Update statistics
    if (result == BW_SUCCESS) {
        index->stats.deletes++;
        index->stats.total_operations++;
    }
    
    return bw_result_to_index_result(result);
}

static index_result_t bw_tree_adapter_update(index_instance_t* index, 
                                           const void* key, size_t key_size,
                                           const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_result_t result = bw_tree_update(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == BW_SUCCESS) {
        index->stats.updates++;
        index->stats.total_operations++;
    }
    
    return bw_result_to_index_result(result);
}

static index_result_t bw_tree_adapter_search(index_instance_t* index, 
                                           const void* key, size_t key_size,
                                           void** value, size_t* value_size) {
    if (!index || !index->index_data || !key || !value || !value_size) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_search_result_t search_result;
    bw_result_t result = bw_tree_search(tree, key, key_size, &search_result);
    
    if (result == BW_SUCCESS) {
        *value = search_result.value;
        *value_size = search_result.value_size;
        index->stats.searches++;
        index->stats.total_operations++;
    }
    
    return bw_result_to_index_result(result);
}

static index_result_t bw_tree_adapter_exists(index_instance_t* index, 
                                            const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_search_result_t search_result;
    bw_result_t result = bw_tree_search(tree, key, key_size, &search_result);
    
    index->stats.searches++;
    index->stats.total_operations++;
    
    return bw_result_to_index_result(result);
}

// Range operations
static index_iterator_t* bw_tree_adapter_range_scan(index_instance_t* index, 
                                                    const void* start_key, size_t start_key_size,
                                                    const void* end_key, size_t end_key_size,
                                                    bool forward) {
    if (!index || !index->index_data) {
        return NULL;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_iterator_t* bw_iter = bw_tree_scan(tree, start_key, start_key_size, end_key, end_key_size, forward);
    
    if (!bw_iter) {
        return NULL;
    }
    
    // Create wrapper iterator
    index_iterator_t* iter = malloc(sizeof(index_iterator_t));
    if (!iter) {
        bw_iterator_destroy(bw_iter);
        return NULL;
    }
    
    iter->index = index;
    iter->iterator_data = bw_iter;
    iter->is_valid = true;
    
    return iter;
}

// Iterator operations
static bool bw_tree_adapter_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return false;
    }
    
    bw_iterator_t* bw_iter = (bw_iterator_t*)iter->iterator_data;
    return bw_iterator_valid(bw_iter);
}

static index_result_t bw_tree_adapter_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_iterator_t* bw_iter = (bw_iterator_t*)iter->iterator_data;
    bw_result_t result = bw_iterator_next(bw_iter);
    
    if (result != BW_SUCCESS) {
        iter->is_valid = false;
    }
    
    return bw_result_to_index_result(result);
}

static index_result_t bw_tree_adapter_iterator_current(index_iterator_t* iter, 
                                                      void** key, size_t* key_size,
                                                      void** value, size_t* value_size) {
    if (!iter || !iter->iterator_data || !key || !key_size || !value || !value_size) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_iterator_t* bw_iter = (bw_iterator_t*)iter->iterator_data;
    bw_result_t result = bw_iterator_current(bw_iter, key, key_size, value, value_size);
    
    return bw_result_to_index_result(result);
}

static void bw_tree_adapter_iterator_destroy(index_iterator_t* iter) {
    if (!iter) return;
    
    if (iter->iterator_data) {
        bw_iterator_t* bw_iter = (bw_iterator_t*)iter->iterator_data;
        bw_iterator_destroy(bw_iter);
    }
    
    free(iter);
}

// Bulk operations
static index_result_t bw_tree_adapter_bulk_insert(index_instance_t* index, 
                                                  const void** keys, size_t* key_sizes,
                                                  const void** values, size_t* value_sizes,
                                                  size_t count) {
    if (!index || !index->index_data || !keys || !key_sizes || !values || !value_sizes || count == 0) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    
    // Convert to bw_kv_pair_t array
    bw_kv_pair_t** pairs = malloc(count * sizeof(bw_kv_pair_t*));
    if (!pairs) {
        return INDEX_OUT_OF_MEMORY;
    }
    
    for (size_t i = 0; i < count; i++) {
        pairs[i] = malloc(sizeof(bw_kv_pair_t));
        if (!pairs[i]) {
            // Clean up allocated memory
            for (size_t j = 0; j < i; j++) {
                free(pairs[j]);
            }
            free(pairs);
            return INDEX_OUT_OF_MEMORY;
        }
        
        pairs[i]->key = (void*)keys[i];
        pairs[i]->key_size = key_sizes[i];
        pairs[i]->value = (void*)values[i];
        pairs[i]->value_size = value_sizes[i];
    }
    
    bw_result_t result = bw_tree_bulk_insert(tree, pairs, count);
    
    // Clean up
    for (size_t i = 0; i < count; i++) {
        free(pairs[i]);
    }
    free(pairs);
    
    if (result == BW_SUCCESS) {
        index->stats.inserts += count;
        index->stats.total_operations += count;
    }
    
    return bw_result_to_index_result(result);
}

static size_t bw_tree_adapter_range_delete(index_instance_t* index,
                                         const void* start_key, size_t start_key_size,
                                         const void* end_key, size_t end_key_size) {
    if (!index || !index->index_data || !start_key || !end_key) {
        return 0;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    size_t deleted_count = bw_tree_range_delete(tree, start_key, start_key_size, end_key, end_key_size);
    
    index->stats.deletes += deleted_count;
    index->stats.total_operations += deleted_count;
    
    return deleted_count;
}

// Management operations
static index_result_t bw_tree_adapter_clear(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    int result = bw_tree_clear(tree);
    
    if (result == 0) {
        // Reset statistics
        memset(&index->stats, 0, sizeof(index_stats_t));
        return INDEX_SUCCESS;
    }
    
    return INDEX_ERROR;
}

static index_result_t bw_tree_adapter_rebuild(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    // Bw-tree doesn't need explicit rebuild due to its delta structure
    // But we can consolidate all nodes if needed
    return INDEX_SUCCESS;
}

static void bw_tree_adapter_destroy(index_instance_t* index) {
    if (!index || !index->index_data) {
        return;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_tree_destroy(tree);
    index->index_data = NULL;
}

// Statistics and monitoring
static void bw_tree_adapter_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !index->index_data || !stats) {
        return;
    }
    
    // Copy basic stats
    memcpy(stats, &index->stats, sizeof(index_stats_t));
    
    // Get detailed Bw-tree stats
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    bw_tree_stats_t bw_stats;
    bw_tree_get_stats(tree, &bw_stats);
    
    // Add Bw-tree specific information
    stats->memory_usage = bw_stats.memory_usage;
    stats->index_specific = malloc(sizeof(bw_tree_stats_t));
    if (stats->index_specific) {
        memcpy(stats->index_specific, &bw_stats, sizeof(bw_tree_stats_t));
    }
}

static bool bw_tree_adapter_validate(index_instance_t* index) {
    if (!index || !index->index_data) {
        return false;
    }
    
    bw_tree_t* tree = (bw_tree_t*)index->index_data;
    return bw_tree_validate(tree);
}

// Configuration
static index_result_t bw_tree_adapter_set_config(index_instance_t* index, const index_config_t* config) {
    if (!index || !index->index_data || !config) {
        return INDEX_INVALID_ARGUMENT;
    }
    
    // Copy configuration
    memcpy(&index->config, config, sizeof(index_config_t));
    
    // Bw-tree specific configuration can be set here
    return INDEX_SUCCESS;
}

static void bw_tree_adapter_get_config(index_instance_t* index, index_config_t* config) {
    if (!index || !config) {
        return;
    }
    
    memcpy(config, &index->config, sizeof(index_config_t));
}

// ============================================================================
// B+ Tree Adapter Implementation
// ============================================================================

// Forward declarations for B+ tree functions
typedef struct btree btree_t;
typedef struct btree_node btree_node_t;
typedef struct btree_iterator btree_iterator_t;

extern btree_t* btree_create(memory_manager_t* memory_mgr, uint32_t node_size);
extern void btree_destroy(btree_t* tree);
extern int btree_insert(btree_t* tree, const void* key, size_t key_size,
                       const void* value, size_t value_size);
extern int btree_delete(btree_t* tree, const void* key, size_t key_size);
extern int btree_update(btree_t* tree, const void* key, size_t key_size,
                       const void* value, size_t value_size);
extern int btree_search(btree_t* tree, const void* key, size_t key_size,
                       void** value, size_t* value_size);
extern btree_iterator_t* btree_scan(btree_t* tree, const void* start_key, size_t start_key_size,
                                   const void* end_key, size_t end_key_size, bool forward);
extern bool btree_iterator_valid(btree_iterator_t* iter);
extern int btree_iterator_next(btree_iterator_t* iter);
extern int btree_iterator_current(btree_iterator_t* iter, void** key, size_t* key_size,
                                 void** value, size_t* value_size);
extern void btree_iterator_destroy(btree_iterator_t* iter);
extern int btree_bulk_insert(btree_t* tree, const void** keys, size_t* key_sizes,
                            const void** values, size_t* value_sizes, size_t count);
extern size_t btree_range_delete(btree_t* tree, const void* start_key, size_t start_key_size,
                                const void* end_key, size_t end_key_size);
extern int btree_clear(btree_t* tree);
extern void btree_get_stats(btree_t* tree, index_stats_t* stats);
extern bool btree_validate(btree_t* tree);

// Helper function to convert B+ tree result to index_result_t
static index_result_t btree_result_to_index_result(int btree_result) {
    switch (btree_result) {
        case 0: return INDEX_SUCCESS;
        case -1: return INDEX_ERROR_KEY_NOT_FOUND;
        case -2: return INDEX_ERROR_KEY_EXISTS;
        case -3: return INDEX_ERROR_INVALID_PARAM;
        case -4: return INDEX_ERROR_OUT_OF_MEMORY;
        case -5: return INDEX_ERROR_INDEX_FULL;
        default: return INDEX_ERROR_TYPE_MISMATCH;
    }
}

// Core operations
static index_result_t btree_adapter_insert(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    int result = btree_insert(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.inserts++;
        index->stats.total_operations++;
    }
    
    return btree_result_to_index_result(result);
}

static index_result_t btree_adapter_delete(index_instance_t* index, 
                                         const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    int result = btree_delete(tree, key, key_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.deletes++;
        index->stats.total_operations++;
    }
    
    return btree_result_to_index_result(result);
}

static index_result_t btree_adapter_update(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    int result = btree_update(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.updates++;
        index->stats.total_operations++;
    }
    
    return btree_result_to_index_result(result);
}

static index_result_t btree_adapter_search(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         index_search_result_t* result) {
    if (!index || !index->index_data || !key || !result) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int btree_result = btree_search(tree, key, key_size, &value, &value_size);
    
    if (btree_result == 0) {
        result->found = true;
        result->value = value;
        result->value_size = value_size;
        index->stats.searches++;
        index->stats.total_operations++;
    } else {
        result->found = false;
        result->value = NULL;
        result->value_size = 0;
    }
    
    return btree_result_to_index_result(btree_result);
}

static index_result_t btree_adapter_exists(index_instance_t* index, 
                                          const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int result = btree_search(tree, key, key_size, &value, &value_size);
    
    index->stats.searches++;
    index->stats.total_operations++;
    
    return btree_result_to_index_result(result);
}

// Range operations
static index_iterator_t* btree_adapter_range_scan(index_instance_t* index, 
                                                 const void* start_key, size_t start_key_size,
                                                 const void* end_key, size_t end_key_size,
                                                 bool forward) {
    if (!index || !index->index_data) {
        return NULL;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    btree_iterator_t* btree_iter = btree_scan(tree, start_key, start_key_size, 
                                               end_key, end_key_size, forward);
    
    if (!btree_iter) {
        return NULL;
    }
    
    // Create wrapper iterator
    index_iterator_t* iter = malloc(sizeof(index_iterator_t));
    if (!iter) {
        btree_iterator_destroy(btree_iter);
        return NULL;
    }
    
    iter->index = index;
    iter->iterator_data = btree_iter;
    iter->is_valid = true;
    
    return iter;
}

// Iterator operations
static bool btree_adapter_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return false;
    }
    
    btree_iterator_t* btree_iter = (btree_iterator_t*)iter->iterator_data;
    return btree_iterator_valid(btree_iter);
}

static index_result_t btree_adapter_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_iterator_t* btree_iter = (btree_iterator_t*)iter->iterator_data;
    int result = btree_iterator_next(btree_iter);
    
    if (result != 0) {
        iter->is_valid = false;
    }
    
    return btree_result_to_index_result(result);
}

static index_result_t btree_adapter_iterator_current(index_iterator_t* iter, 
                                                  void** key, size_t* key_size,
                                                  void** value, size_t* value_size) {
    if (!iter || !iter->iterator_data || !key || !key_size || !value || !value_size) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_iterator_t* btree_iter = (btree_iterator_t*)iter->iterator_data;
    int result = btree_iterator_current(btree_iter, key, key_size, value, value_size);
    
    return btree_result_to_index_result(result);
}

static void btree_adapter_iterator_destroy(index_iterator_t* iter) {
    if (!iter) return;
    
    if (iter->iterator_data) {
        btree_iterator_t* btree_iter = (btree_iterator_t*)iter->iterator_data;
        btree_iterator_destroy(btree_iter);
    }
    
    free(iter);
}

// Bulk operations
static index_result_t btree_adapter_bulk_insert(index_instance_t* index, 
                                               const void** keys, size_t* key_sizes,
                                               const void** values, size_t* value_sizes,
                                               size_t count) {
    if (!index || !index->index_data || !keys || !key_sizes || !values || !value_sizes || count == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    int result = btree_bulk_insert(tree, keys, key_sizes, values, value_sizes, count);
    
    if (result == 0) {
        index->stats.inserts += count;
        index->stats.total_operations += count;
    }
    
    return btree_result_to_index_result(result);
}

static size_t btree_adapter_range_delete(index_instance_t* index,
                                        const void* start_key, size_t start_key_size,
                                        const void* end_key, size_t end_key_size) {
    if (!index || !index->index_data || !start_key || !end_key) {
        return 0;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    size_t deleted_count = btree_range_delete(tree, start_key, start_key_size, end_key, end_key_size);
    
    index->stats.deletes += deleted_count;
    index->stats.total_operations += deleted_count;
    
    return deleted_count;
}

// Management operations
static index_result_t btree_adapter_clear(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    int result = btree_clear(tree);
    
    if (result == 0) {
        // Reset statistics
        memset(&index->stats, 0, sizeof(index_stats_t));
        return INDEX_SUCCESS;
    }
    
    return INDEX_ERROR;
}

static index_result_t btree_adapter_rebuild(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // B+ tree rebuild optimization - rebalance the tree
    btree_t* tree = (btree_t*)index->index_data;
    
    // For B+ tree, we can optimize by rebuilding the tree structure
    // This would involve creating a new tree and inserting all keys in sorted order
    return INDEX_SUCCESS;
}

static void btree_adapter_destroy(index_instance_t* index) {
    if (!index || !index->index_data) {
        return;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    btree_destroy(tree);
    index->index_data = NULL;
}

// Statistics and monitoring
static void btree_adapter_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !index->index_data || !stats) {
        return;
    }
    
    // Copy basic stats
    memcpy(stats, &index->stats, sizeof(index_stats_t));
    
    // Get detailed B+ tree stats
    btree_t* tree = (btree_t*)index->index_data;
    btree_get_stats(tree, stats);
    
    // B+ tree specific statistics would be added here
    stats->avg_depth = 0.0; // Would be calculated from tree height
    stats->memory_usage = 0; // Would be calculated from tree structure
}

static bool btree_adapter_validate(index_instance_t* index) {
    if (!index || !index->index_data) {
        return false;
    }
    
    btree_t* tree = (btree_t*)index->index_data;
    return btree_validate(tree);
}

// Configuration
static index_result_t btree_adapter_set_config(index_instance_t* index, const index_config_t* config) {
    if (!index || !index->index_data || !config) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // Copy configuration
    memcpy(&index->config, config, sizeof(index_config_t));
    
    // B+ tree specific configuration can be set here
    // For example, node size, order, etc.
    return INDEX_SUCCESS;
}

static void btree_adapter_get_config(index_instance_t* index, index_config_t* config) {
    if (!index || !config) {
        return;
    }
    
    memcpy(config, &index->config, sizeof(index_config_t));
}

// ============================================================================
// Bitmap Index Adapter Implementation
// ============================================================================

// Forward declarations for bitmap index functions
typedef struct bitmap_index bitmap_index_t;
typedef struct bitmap_iterator bitmap_iterator_t;

extern bitmap_index_t* bitmap_index_create(memory_manager_t* memory_mgr, uint32_t initial_capacity);
extern void bitmap_index_destroy(bitmap_index_t* index);
extern int bitmap_index_insert(bitmap_index_t* index, const void* key, size_t key_size,
                              const void* value, size_t value_size);
extern int bitmap_index_delete(bitmap_index_t* index, const void* key, size_t key_size);
extern int bitmap_index_update(bitmap_index_t* index, const void* key, size_t key_size,
                              const void* value, size_t value_size);
extern int bitmap_index_search(bitmap_index_t* index, const void* key, size_t key_size,
                              void** value, size_t* value_size);
extern bitmap_iterator_t* bitmap_index_scan(bitmap_index_t* index, const void* start_key, size_t start_key_size,
                                           const void* end_key, size_t end_key_size, bool forward);
extern bool bitmap_iterator_valid(bitmap_iterator_t* iter);
extern int bitmap_iterator_next(bitmap_iterator_t* iter);
extern int bitmap_iterator_current(bitmap_iterator_t* iter, void** key, size_t* key_size,
                                 void** value, size_t* value_size);
extern void bitmap_iterator_destroy(bitmap_iterator_t* iter);
extern int bitmap_index_bulk_insert(bitmap_index_t* index, const void** keys, size_t* key_sizes,
                                  const void** values, size_t* value_sizes, size_t count);
extern size_t bitmap_index_range_delete(bitmap_index_t* index, const void* start_key, size_t start_key_size,
                                       const void* end_key, size_t end_key_size);
extern int bitmap_index_clear(bitmap_index_t* index);
extern void bitmap_index_get_stats(bitmap_index_t* index, index_stats_t* stats);
extern bool bitmap_index_validate(bitmap_index_t* index);

// Helper function to convert bitmap result to index_result_t
static index_result_t bitmap_result_to_index_result(int bitmap_result) {
    switch (bitmap_result) {
        case 0: return INDEX_SUCCESS;
        case -1: return INDEX_ERROR_KEY_NOT_FOUND;
        case -2: return INDEX_ERROR_KEY_EXISTS;
        case -3: return INDEX_ERROR_INVALID_PARAM;
        case -4: return INDEX_ERROR_OUT_OF_MEMORY;
        case -5: return INDEX_ERROR_INDEX_FULL;
        default: return INDEX_ERROR_TYPE_MISMATCH;
    }
}

// Core operations
static index_result_t bitmap_adapter_insert(index_instance_t* index, 
                                          const void* key, size_t key_size,
                                          const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    int result = bitmap_index_insert(bitmap, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.inserts++;
        index->stats.total_operations++;
    }
    
    return bitmap_result_to_index_result(result);
}

static index_result_t bitmap_adapter_delete(index_instance_t* index, 
                                          const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    int result = bitmap_index_delete(bitmap, key, key_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.deletes++;
        index->stats.total_operations++;
    }
    
    return bitmap_result_to_index_result(result);
}

static index_result_t bitmap_adapter_update(index_instance_t* index, 
                                          const void* key, size_t key_size,
                                          const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    int result = bitmap_index_update(bitmap, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.updates++;
        index->stats.total_operations++;
    }
    
    return bitmap_result_to_index_result(result);
}

static index_result_t bitmap_adapter_search(index_instance_t* index, 
                                          const void* key, size_t key_size,
                                          index_search_result_t* result) {
    if (!index || !index->index_data || !key || !result) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int bitmap_result = bitmap_index_search(bitmap, key, key_size, &value, &value_size);
    
    if (bitmap_result == 0) {
        result->found = true;
        result->value = value;
        result->value_size = value_size;
        index->stats.searches++;
        index->stats.total_operations++;
    } else {
        result->found = false;
        result->value = NULL;
        result->value_size = 0;
    }
    
    return bitmap_result_to_index_result(bitmap_result);
}

static index_result_t bitmap_adapter_exists(index_instance_t* index, 
                                           const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int result = bitmap_index_search(bitmap, key, key_size, &value, &value_size);
    
    index->stats.searches++;
    index->stats.total_operations++;
    
    return bitmap_result_to_index_result(result);
}

// Range operations (limited for bitmap indexes)
static index_iterator_t* bitmap_adapter_range_scan(index_instance_t* index, 
                                                  const void* start_key, size_t start_key_size,
                                                  const void* end_key, size_t end_key_size,
                                                  bool forward) {
    if (!index || !index->index_data) {
        return NULL;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    bitmap_iterator_t* bitmap_iter = bitmap_index_scan(bitmap, start_key, start_key_size, 
                                                     end_key, end_key_size, forward);
    
    if (!bitmap_iter) {
        return NULL;
    }
    
    // Create wrapper iterator
    index_iterator_t* iter = malloc(sizeof(index_iterator_t));
    if (!iter) {
        bitmap_iterator_destroy(bitmap_iter);
        return NULL;
    }
    
    iter->index = index;
    iter->iterator_data = bitmap_iter;
    iter->is_valid = true;
    
    return iter;
}

// Iterator operations
static bool bitmap_adapter_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return false;
    }
    
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->iterator_data;
    return bitmap_iterator_valid(bitmap_iter);
}

static index_result_t bitmap_adapter_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->iterator_data;
    int result = bitmap_iterator_next(bitmap_iter);
    
    if (result != 0) {
        iter->is_valid = false;
    }
    
    return bitmap_result_to_index_result(result);
}

static index_result_t bitmap_adapter_iterator_current(index_iterator_t* iter, 
                                                     void** key, size_t* key_size,
                                                     void** value, size_t* value_size) {
    if (!iter || !iter->iterator_data || !key || !key_size || !value || !value_size) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->iterator_data;
    int result = bitmap_iterator_current(bitmap_iter, key, key_size, value, value_size);
    
    return bitmap_result_to_index_result(result);
}

static void bitmap_adapter_iterator_destroy(index_iterator_t* iter) {
    if (!iter) return;
    
    if (iter->iterator_data) {
        bitmap_iterator_t* bitmap_iter = (bitmap_iterator_t*)iter->iterator_data;
        bitmap_iterator_destroy(bitmap_iter);
    }
    
    free(iter);
}

// Bulk operations
static index_result_t bitmap_adapter_bulk_insert(index_instance_t* index, 
                                                const void** keys, size_t* key_sizes,
                                                const void** values, size_t* value_sizes,
                                                size_t count) {
    if (!index || !index->index_data || !keys || !key_sizes || !values || !value_sizes || count == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    int result = bitmap_index_bulk_insert(bitmap, keys, key_sizes, values, value_sizes, count);
    
    if (result == 0) {
        index->stats.inserts += count;
        index->stats.total_operations += count;
    }
    
    return bitmap_result_to_index_result(result);
}

static size_t bitmap_adapter_range_delete(index_instance_t* index,
                                         const void* start_key, size_t start_key_size,
                                         const void* end_key, size_t end_key_size) {
    if (!index || !index->index_data || !start_key || !end_key) {
        return 0;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    size_t deleted_count = bitmap_index_range_delete(bitmap, start_key, start_key_size, end_key, end_key_size);
    
    index->stats.deletes += deleted_count;
    index->stats.total_operations += deleted_count;
    
    return deleted_count;
}

// Management operations
static index_result_t bitmap_adapter_clear(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    int result = bitmap_index_clear(bitmap);
    
    if (result == 0) {
        // Reset statistics
        memset(&index->stats, 0, sizeof(index_stats_t));
        return INDEX_SUCCESS;
    }
    
    return INDEX_ERROR;
}

static index_result_t bitmap_adapter_rebuild(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // Bitmap index rebuild - optimize bitmap compression
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    
    // For bitmap index, rebuild can optimize bitmap compression
    return INDEX_SUCCESS;
}

static void bitmap_adapter_destroy(index_instance_t* index) {
    if (!index || !index->index_data) {
        return;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    bitmap_index_destroy(bitmap);
    index->index_data = NULL;
}

// Statistics and monitoring
static void bitmap_adapter_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !index->index_data || !stats) {
        return;
    }
    
    // Copy basic stats
    memcpy(stats, &index->stats, sizeof(index_stats_t));
    
    // Get detailed bitmap index stats
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    bitmap_index_get_stats(bitmap, stats);
    
    // Bitmap index specific statistics
    stats->memory_usage = 0; // Would be calculated from bitmap size
    stats->avg_chain_length = 0.0; // Not applicable for bitmap
}

static bool bitmap_adapter_validate(index_instance_t* index) {
    if (!index || !index->index_data) {
        return false;
    }
    
    bitmap_index_t* bitmap = (bitmap_index_t*)index->index_data;
    return bitmap_index_validate(bitmap);
}

// Configuration
static index_result_t bitmap_adapter_set_config(index_instance_t* index, const index_config_t* config) {
    if (!index || !index->index_data || !config) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // Copy configuration
    memcpy(&index->config, config, sizeof(index_config_t));
    
    // Bitmap index specific configuration
    return INDEX_SUCCESS;
}

static void bitmap_adapter_get_config(index_instance_t* index, index_config_t* config) {
    if (!index || !config) {
        return;
    }
    
    memcpy(config, &index->config, sizeof(index_config_t));
}

// ============================================================================
// R-Tree Adapter Implementation
// ============================================================================

// Forward declarations for R-tree functions
typedef struct rtree rtree_t;
typedef struct rtree_node rtree_node_t;
typedef struct rtree_iterator rtree_iterator_t;
typedef struct rtree_rect rtree_rect_t;

extern rtree_t* rtree_create(memory_manager_t* memory_mgr, uint32_t node_size);
extern void rtree_destroy(rtree_t* tree);
extern int rtree_insert(rtree_t* tree, const void* key, size_t key_size,
                       const void* value, size_t value_size);
extern int rtree_delete(rtree_t* tree, const void* key, size_t key_size);
extern int rtree_update(rtree_t* tree, const void* key, size_t key_size,
                       const void* value, size_t value_size);
extern int rtree_search(rtree_t* tree, const void* key, size_t key_size,
                       void** value, size_t* value_size);
extern rtree_iterator_t* rtree_scan(rtree_t* tree, const void* start_key, size_t start_key_size,
                                   const void* end_key, size_t end_key_size, bool forward);
extern bool rtree_iterator_valid(rtree_iterator_t* iter);
extern int rtree_iterator_next(rtree_iterator_t* iter);
extern int rtree_iterator_current(rtree_iterator_t* iter, void** key, size_t* key_size,
                                 void** value, size_t* value_size);
extern void rtree_iterator_destroy(rtree_iterator_t* iter);
extern int rtree_bulk_insert(rtree_t* tree, const void** keys, size_t* key_sizes,
                            const void** values, size_t* value_sizes, size_t count);
extern size_t rtree_range_delete(rtree_t* tree, const void* start_key, size_t start_key_size,
                                const void* end_key, size_t end_key_size);
extern int rtree_clear(rtree_t* tree);
extern void rtree_get_stats(rtree_t* tree, index_stats_t* stats);
extern bool rtree_validate(rtree_t* tree);

// Helper function to convert R-tree result to index_result_t
static index_result_t rtree_result_to_index_result(int rtree_result) {
    switch (rtree_result) {
        case 0: return INDEX_SUCCESS;
        case -1: return INDEX_ERROR_KEY_NOT_FOUND;
        case -2: return INDEX_ERROR_KEY_EXISTS;
        case -3: return INDEX_ERROR_INVALID_PARAM;
        case -4: return INDEX_ERROR_OUT_OF_MEMORY;
        case -5: return INDEX_ERROR_INDEX_FULL;
        default: return INDEX_ERROR_TYPE_MISMATCH;
    }
}

// Core operations
static index_result_t rtree_adapter_insert(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    int result = rtree_insert(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.inserts++;
        index->stats.total_operations++;
    }
    
    return rtree_result_to_index_result(result);
}

static index_result_t rtree_adapter_delete(index_instance_t* index, 
                                         const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    int result = rtree_delete(tree, key, key_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.deletes++;
        index->stats.total_operations++;
    }
    
    return rtree_result_to_index_result(result);
}

static index_result_t rtree_adapter_update(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         const void* value, size_t value_size) {
    if (!index || !index->index_data || !key || !value) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    int result = rtree_update(tree, key, key_size, value, value_size);
    
    // Update statistics
    if (result == 0) {
        index->stats.updates++;
        index->stats.total_operations++;
    }
    
    return rtree_result_to_index_result(result);
}

static index_result_t rtree_adapter_search(index_instance_t* index, 
                                         const void* key, size_t key_size,
                                         index_search_result_t* result) {
    if (!index || !index->index_data || !key || !result) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int rtree_result = rtree_search(tree, key, key_size, &value, &value_size);
    
    if (rtree_result == 0) {
        result->found = true;
        result->value = value;
        result->value_size = value_size;
        index->stats.searches++;
        index->stats.total_operations++;
    } else {
        result->found = false;
        result->value = NULL;
        result->value_size = 0;
    }
    
    return rtree_result_to_index_result(rtree_result);
}

static index_result_t rtree_adapter_exists(index_instance_t* index, 
                                          const void* key, size_t key_size) {
    if (!index || !index->index_data || !key) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    void* value = NULL;
    size_t value_size = 0;
    int result = rtree_search(tree, key, key_size, &value, &value_size);
    
    index->stats.searches++;
    index->stats.total_operations++;
    
    return rtree_result_to_index_result(result);
}

// Range operations (spatial queries for R-tree)
static index_iterator_t* rtree_adapter_range_scan(index_instance_t* index, 
                                                 const void* start_key, size_t start_key_size,
                                                 const void* end_key, size_t end_key_size,
                                                 bool forward) {
    if (!index || !index->index_data) {
        return NULL;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    rtree_iterator_t* rtree_iter = rtree_scan(tree, start_key, start_key_size, 
                                             end_key, end_key_size, forward);
    
    if (!rtree_iter) {
        return NULL;
    }
    
    // Create wrapper iterator
    index_iterator_t* iter = malloc(sizeof(index_iterator_t));
    if (!iter) {
        rtree_iterator_destroy(rtree_iter);
        return NULL;
    }
    
    iter->index = index;
    iter->iterator_data = rtree_iter;
    iter->is_valid = true;
    
    return iter;
}

// Iterator operations
static bool rtree_adapter_iterator_valid(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return false;
    }
    
    rtree_iterator_t* rtree_iter = (rtree_iterator_t*)iter->iterator_data;
    return rtree_iterator_valid(rtree_iter);
}

static index_result_t rtree_adapter_iterator_next(index_iterator_t* iter) {
    if (!iter || !iter->iterator_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_iterator_t* rtree_iter = (rtree_iterator_t*)iter->iterator_data;
    int result = rtree_iterator_next(rtree_iter);
    
    if (result != 0) {
        iter->is_valid = false;
    }
    
    return rtree_result_to_index_result(result);
}

static index_result_t rtree_adapter_iterator_current(index_iterator_t* iter, 
                                                  void** key, size_t* key_size,
                                                  void** value, size_t* value_size) {
    if (!iter || !iter->iterator_data || !key || !key_size || !value || !value_size) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_iterator_t* rtree_iter = (rtree_iterator_t*)iter->iterator_data;
    int result = rtree_iterator_current(rtree_iter, key, key_size, value, value_size);
    
    return rtree_result_to_index_result(result);
}

static void rtree_adapter_iterator_destroy(index_iterator_t* iter) {
    if (!iter) return;
    
    if (iter->iterator_data) {
        rtree_iterator_t* rtree_iter = (rtree_iterator_t*)iter->iterator_data;
        rtree_iterator_destroy(rtree_iter);
    }
    
    free(iter);
}

// Bulk operations
static index_result_t rtree_adapter_bulk_insert(index_instance_t* index, 
                                               const void** keys, size_t* key_sizes,
                                               const void** values, size_t* value_sizes,
                                               size_t count) {
    if (!index || !index->index_data || !keys || !key_sizes || !values || !value_sizes || count == 0) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    int result = rtree_bulk_insert(tree, keys, key_sizes, values, value_sizes, count);
    
    if (result == 0) {
        index->stats.inserts += count;
        index->stats.total_operations += count;
    }
    
    return rtree_result_to_index_result(result);
}

static size_t rtree_adapter_range_delete(index_instance_t* index,
                                        const void* start_key, size_t start_key_size,
                                        const void* end_key, size_t end_key_size) {
    if (!index || !index->index_data || !start_key || !end_key) {
        return 0;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    size_t deleted_count = rtree_range_delete(tree, start_key, start_key_size, end_key, end_key_size);
    
    index->stats.deletes += deleted_count;
    index->stats.total_operations += deleted_count;
    
    return deleted_count;
}

// Management operations
static index_result_t rtree_adapter_clear(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    int result = rtree_clear(tree);
    
    if (result == 0) {
        // Reset statistics
        memset(&index->stats, 0, sizeof(index_stats_t));
        return INDEX_SUCCESS;
    }
    
    return INDEX_ERROR;
}

static index_result_t rtree_adapter_rebuild(index_instance_t* index) {
    if (!index || !index->index_data) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // R-tree rebuild - rebalance the tree structure
    rtree_t* tree = (rtree_t*)index->index_data;
    
    // For R-tree, rebuild can optimize the tree structure
    // This would involve creating a new tree and inserting all objects with better bounding boxes
    return INDEX_SUCCESS;
}

static void rtree_adapter_destroy(index_instance_t* index) {
    if (!index || !index->index_data) {
        return;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    rtree_destroy(tree);
    index->index_data = NULL;
}

// Statistics and monitoring
static void rtree_adapter_get_stats(index_instance_t* index, index_stats_t* stats) {
    if (!index || !index->index_data || !stats) {
        return;
    }
    
    // Copy basic stats
    memcpy(stats, &index->stats, sizeof(index_stats_t));
    
    // Get detailed R-tree stats
    rtree_t* tree = (rtree_t*)index->index_data;
    rtree_get_stats(tree, stats);
    
    // R-tree specific statistics
    stats->avg_depth = 0.0; // Would be calculated from tree height
    stats->memory_usage = 0; // Would be calculated from tree structure
}

static bool rtree_adapter_validate(index_instance_t* index) {
    if (!index || !index->index_data) {
        return false;
    }
    
    rtree_t* tree = (rtree_t*)index->index_data;
    return rtree_validate(tree);
}

// Configuration
static index_result_t rtree_adapter_set_config(index_instance_t* index, const index_config_t* config) {
    if (!index || !index->index_data || !config) {
        return INDEX_ERROR_INVALID_PARAM;
    }
    
    // Copy configuration
    memcpy(&index->config, config, sizeof(index_config_t));
    
    // R-tree specific configuration (node size, splitting strategy, etc.)
    return INDEX_SUCCESS;
}

static void rtree_adapter_get_config(index_instance_t* index, index_config_t* config) {
    if (!index || !config) {
        return;
    }
    
    memcpy(config, &index->config, sizeof(index_config_t));
}